home *** CD-ROM | disk | FTP | other *** search
/ The CICA Windows Explosion! / The CICA Windows Explosion! - Disc 2.iso / programr / dpmigcc5.zip / RSX / SOURCE / FPU-EMU / PRINTK.C < prev    next >
C/C++ Source or Header  |  1994-05-27  |  7KB  |  318 lines

  1. #include <string.h>
  2. #include <stdarg.h>
  3. #include <sys\types.h>
  4.  
  5. int        printk(const char *fmt,...);
  6. int        sprintf(char * buf, const char *fmt, ...);
  7. static int    vsprintf(char *, const char *, va_list);
  8. static int    skip_atoi(const char **);
  9. static char *    number(char *, long, int, int, int, int);
  10.  
  11. static void console_print(const char * buffer)
  12. {
  13.     __asm__ __volatile__(
  14.     "movb   $0x09, %%ah \n\t"
  15.     "int    $0x21 \n\t"
  16.     : : "dx" ((int) buffer)
  17.     );
  18. }
  19.  
  20. int printk(const char *fmt, ...)
  21. {
  22.     char buf[5*80];
  23.     char buf2[5*80];
  24.     va_list args;
  25.     int i,j;
  26.  
  27.     va_start(args, fmt);
  28.     vsprintf(buf,fmt,args);
  29.     va_end(args);
  30.  
  31.     for (i=0,j=0; buf[i]; i++,j++) {
  32.         buf2[j]=buf[i];
  33.         if (buf2[j]=='\n')
  34.         buf2[++j]='\r';
  35.         }
  36.     buf2[j]='$';
  37.  
  38.     console_print(buf2);
  39.     return i;
  40. }
  41.  
  42. int sprintf(char * buf, const char *fmt, ...)
  43. {
  44.     va_list args;
  45.     int i;
  46.  
  47.     va_start(args, fmt);
  48.     i=vsprintf(buf,fmt,args);
  49.     va_end(args);
  50.     return i;
  51. }
  52.  
  53. static size_t
  54. strlen(const char *str)
  55. {
  56.     register const char *s;
  57.  
  58.     for (s = str; *s; ++s);
  59.     return (s - str);
  60. }
  61.  
  62. /* we use this so that we can do without the ctype library */
  63. #define is_digit(c)    ((c) >= '0' && (c) <= '9')
  64.  
  65. static int
  66. skip_atoi(const char **s)
  67. {
  68.     int         i = 0;
  69.  
  70.     while (is_digit(**s))
  71.     i = i * 10 + *((*s)++) - '0';
  72.     return i;
  73. }
  74.  
  75. #define ZEROPAD 1        /* pad with zero */
  76. #define SIGN    2        /* unsigned/signed long */
  77. #define PLUS    4        /* show plus */
  78. #define SPACE    8        /* space if plus */
  79. #define LEFT    16        /* left justified */
  80. #define SPECIAL 32        /* 0x */
  81. #define SMALL    64        /* use 'abcdef' instead of 'ABCDEF' */
  82.  
  83. #ifdef __EMX__
  84. #define do_div(n,base) ({      \
  85. int __res; \              \
  86. __asm__("divl %4"                 \
  87.     :"=a" (n), "=d" (__res)       \
  88.     :"0" (n),"1" (0),"r" (base)); \
  89. __res; })
  90. #else
  91. #define do_div(n,base) ({ \
  92.     unsigned long _res = (unsigned long) n % (unsigned long) base; \
  93.     n = (unsigned long) n / (unsigned long) base; \
  94.     (unsigned) _res; })
  95. #endif
  96.  
  97. static char    *
  98. number(char *str, long num, int base, int size, int precision, int type)
  99. {
  100.     char        c, sign, tmp[36];
  101.     const char       *digits = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ";
  102.     int         i;
  103.  
  104.     if (type & SMALL)
  105.     digits = "0123456789abcdefghijklmnopqrstuvwxyz";
  106.     if (type & LEFT)
  107.     type &= ~ZEROPAD;
  108.     if (base < 2 || base > 36)
  109.     return 0;
  110.     c = (type & ZEROPAD) ? '0' : ' ';
  111.     if (type & SIGN && num < 0) {
  112.     sign = '-';
  113.     num = -num;
  114.     } else
  115.     sign = (type & PLUS) ? '+' : ((type & SPACE) ? ' ' : 0);
  116.     if (sign)
  117.     size--;
  118.     if (type & SPECIAL)
  119.     if (base == 16)
  120.         size -= 2;
  121.     else if (base == 8)
  122.         size--;
  123.     i = 0;
  124.     if (num == 0)
  125.     tmp[i++] = '0';
  126.     else
  127.     while (num != 0) {
  128.         unsigned long _res = (unsigned long) num % (unsigned long) base;
  129.         num = (unsigned long) num / (unsigned long) base;
  130.         tmp[i++] = digits[_res];
  131.     }
  132.     if (i > precision)
  133.     precision = i;
  134.     size -= precision;
  135.     if (!(type & (ZEROPAD + LEFT)))
  136.     while (size-- > 0)
  137.         *str++ = ' ';
  138.     if (sign)
  139.     *str++ = sign;
  140.     if (type & SPECIAL)
  141.     if (base == 8)
  142.         *str++ = '0';
  143.     else if (base == 16) {
  144.         *str++ = '0';
  145.         *str++ = digits[33];
  146.     }
  147.     if (!(type & LEFT))
  148.     while (size-- > 0)
  149.         *str++ = c;
  150.     while (i < precision--)
  151.     *str++ = '0';
  152.     while (i-- > 0)
  153.     *str++ = tmp[i];
  154.     while (size-- > 0)
  155.     *str++ = ' ';
  156.     return str;
  157. }
  158.  
  159. static int
  160. vsprintf(char *buf, const char *fmt, va_list args)
  161. {
  162.     int         len;
  163.     int         i;
  164.     char       *str;
  165.     char       *s;
  166.     int        *ip;
  167.  
  168.     int         flags;    /* flags to number() */
  169.  
  170.     int         field_width;/* width of output field */
  171.     int         precision;    /* min. # of digits for integers; max number
  172.                  * of chars for from string */
  173.     int         qualifier;    /* 'h', 'l', or 'L' for integer fields */
  174.     int         use_long = 0;
  175.  
  176.     for (str = buf; *fmt; ++fmt) {
  177.     if (*fmt != '%') {
  178.         *str++ = *fmt;
  179.         continue;
  180.     }
  181.     /* process flags */
  182.     flags = 0;
  183.       repeat:
  184.     ++fmt;            /* this also skips first '%' */
  185.     switch (*fmt) {
  186.     case '-':
  187.         flags |= LEFT;
  188.         goto repeat;
  189.     case '+':
  190.         flags |= PLUS;
  191.         goto repeat;
  192.     case ' ':
  193.         flags |= SPACE;
  194.         goto repeat;
  195.     case '#':
  196.         flags |= SPECIAL;
  197.         goto repeat;
  198.     case '0':
  199.         flags |= ZEROPAD;
  200.         goto repeat;
  201.     }
  202.  
  203.     /* get field width */
  204.     field_width = -1;
  205.     if (is_digit(*fmt))
  206.         field_width = skip_atoi(&fmt);
  207.     else if (*fmt == '*') {
  208.         /* it's the next argument */
  209.         field_width = va_arg(args, int);
  210.         if (field_width < 0) {
  211.         field_width = -field_width;
  212.         flags |= LEFT;
  213.         }
  214.     }
  215.     /* get the precision */
  216.     precision = -1;
  217.     if (*fmt == '.') {
  218.         ++fmt;
  219.         if (is_digit(*fmt))
  220.         precision = skip_atoi(&fmt);
  221.         else if (*fmt == '*') {
  222.         /* it's the next argument */
  223.         precision = va_arg(args, int);
  224.         }
  225.         if (precision < 0)
  226.         precision = 0;
  227.     }
  228.     /* get the conversion qualifier */
  229.     qualifier = -1;
  230.     if (*fmt == 'h' || *fmt == 'l' || *fmt == 'L') {
  231.         if (*fmt != 'h')
  232.         use_long = 1;
  233.         qualifier = *fmt;
  234.         ++fmt;
  235.     }
  236.     switch (*fmt) {
  237.     case 'c':
  238.         if (!(flags & LEFT))
  239.         while (--field_width > 0)
  240.             *str++ = ' ';
  241.         *str++ = (unsigned char) va_arg(args, int);
  242.         while (--field_width > 0)
  243.         *str++ = ' ';
  244.         break;
  245.  
  246.     case 's':
  247.         s = va_arg(args, char *);
  248.         len = strlen(s);
  249.         if (precision < 0)
  250.         precision = len;
  251.         else if (len > precision)
  252.         len = precision;
  253.  
  254.         if (!(flags & LEFT))
  255.         while (len < field_width--)
  256.             *str++ = ' ';
  257.         for (i = 0; i < len; ++i)
  258.         *str++ = *s++;
  259.         while (len < field_width--)
  260.         *str++ = ' ';
  261.         break;
  262.  
  263.     case 'o':
  264.         str = number(str, va_arg(args, unsigned), 8,
  265.              field_width, precision, flags);
  266.         break;
  267.  
  268.     case 'p':
  269.         if (field_width == -1) {
  270.         field_width = 8;
  271.         flags |= ZEROPAD;
  272.         }
  273.         str = number(str, (unsigned) va_arg(args, void *), 16,
  274.              field_width, precision, flags);
  275.         break;
  276.  
  277.     case 'x':
  278.         flags |= SMALL;
  279.     case 'X':
  280.         if (use_long)
  281.         str = number(str, va_arg(args, unsigned long), 16,
  282.                  field_width, precision, flags);
  283.         else
  284.         str = number(str, va_arg(args, unsigned), 16,
  285.                  field_width, precision, flags);
  286.         break;
  287.  
  288.     case 'd':
  289.     case 'i':
  290.         flags |= SIGN;
  291.     case 'u':
  292.         if (use_long)
  293.         str = number(str, va_arg(args, unsigned), 10,
  294.                  field_width, precision, flags);
  295.         else
  296.         str = number(str, va_arg(args, unsigned long), 10,
  297.                  field_width, precision, flags);
  298.         break;
  299.  
  300.     case 'n':
  301.         ip = va_arg(args, int *);
  302.         *ip = (str - buf);
  303.         break;
  304.  
  305.     default:
  306.         if (*fmt != '%')
  307.         *str++ = '%';
  308.         if (*fmt)
  309.         *str++ = *fmt;
  310.         else
  311.         --fmt;
  312.         break;
  313.     }
  314.     }
  315.     *str = '\0';
  316.     return str - buf;
  317. }
  318.